package com.matt.service.impl;

import com.matt.domain.Feeds;
import com.matt.domain.course.ChildrenCourseItem;
import com.matt.domain.course.CoursePlanClasses;
import com.matt.domain.observation.*;
import com.matt.foundation.DO.ChildListDO;
import com.matt.foundation.DO.ChildrenCheckRecordDO;
import com.matt.foundation.DO.ChildrenCourseItemDO;
import com.matt.foundation.constant.ChildrenCourseConstant;
import com.matt.foundation.constant.CourseConstant;
import com.matt.foundation.constant.FeedsConstant;
import com.matt.commons.exception.BusinessException;
import com.matt.foundation.utils.JsonValidateUtil;
import com.matt.foundation.vo.observation.ObservationChildrenListVo;
import com.matt.foundation.vo.observation.ObservationNewVo;
import com.matt.repository.base.ChildChildrenCourseItemRepository;
import com.matt.repository.base.ChildrenObservationRecordRepository;
import com.matt.repository.course.ChildrenCourseItemRepository;
import com.matt.repository.course.CoursePlanClassesRepository;
import com.matt.repository.observation.*;
import com.matt.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.transaction.Transactional;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.matt.foundation.model.ErrorCode.CATEGORY_ERROR;
import static com.matt.foundation.model.ErrorCode.OBSERVATION_TESTED;

/**
 * *******************************
 * Created by Ron.
 * form com.matt
 * on 2017/8/14
 * *******************************
 */
@Service
@Slf4j
public class ObservationNewServiceImpl implements ObservationNewService {


    @Autowired
    private ObservationNewRepository observationNewRepository;

    @Autowired
    private ObservationNewOptionRepository observationNewOptionRepository;

    @Autowired
    private ObservationNewRecordRepository observationNewRecordRepository;

    @Autowired
    private ChildrenCourseItemRepository childrenCourseItemRepository;

    @Autowired
    private CoursePlanClassesRepository coursePlanClassesRepository;

    @Autowired
    private UploadService uploadService;

    @Autowired
    private ObservationNewTypeRepository observationNewTypeRepository;

    @Autowired
    private ChildrenObservationRecordRepository childrenObservationRecordRepository;

    @Autowired
    private ChildrenService childrenService;

    @Autowired
    private ChildChildrenCourseItemRepository childChildrenCourseItemRepository;

    @Autowired
    private ObservationNewQuestionRecordRepository observationNewQuestionRecordRepository;

    @Autowired
    private FeedsService feedsService;

    @Autowired
    private WxPushService wxPushService;

    @Override
    public List getObservationByPlan(String coursePlanId, Integer category) {
        List<ObservationNew> observations;
        CoursePlanClasses coursePlanClasses =  coursePlanClassesRepository.getOne(coursePlanId);
        if (Objects.isNull(coursePlanClasses))
            throw new BusinessException(CATEGORY_ERROR, "班级类型错误");

        if (CourseConstant.Category.NURSERY.codeOf() == category){
            // TODO 待验证
            observations = observationNewRepository.findByCoursePlanIdAndCategory(coursePlanId, CourseConstant.Category.NURSERY.codeOf());
            List<ObservationNewVo> observationList = Lists.newArrayList();
            if(Objects.isNull(observations)||observations.size()<=0){
            	observations=observationNewRepository.findByCoursePlanIdAndCategory(coursePlanClasses.getId(), CourseConstant.Category.NURSERY.codeOf());
            }
            observations.forEach(o -> {
                List<ObservationNewOption> optionList = observationNewOptionRepository.findByObservationIdAndDeleted(o.getId(), false);
                observationList.add(ObservationNewVo.of(o, optionList));
            });
            return observationList;
        }else {
            if (CourseConstant.CourseType.SAT.codeOf() != coursePlanClasses.getCourseType()){
                observations = observationNewRepository.findByCoursePlanIdAndCategory(coursePlanId, CourseConstant.Category.EARLY.codeOf());
                List<ObservationNewVo> observationList = Lists.newArrayList();
                observations.forEach(o -> {
                    List<ObservationNewOption> optionList = observationNewOptionRepository.findByObservationIdAndDeleted(o.getId(), false);
                    observationList.add(ObservationNewVo.of(o, optionList));
                });
                return observationList;
            }else {
                observations = observationNewRepository.findByCategoryAndCourseTypeOrderByTypeCode(CourseConstant.Category.EARLY.codeOf(), CourseConstant.CourseType.SAT.codeOf());
                List<ObservationNewVo> observationList = Lists.newArrayList();
                observations.forEach(o -> {
                    List<ObservationNewOption> optionList = observationNewOptionRepository.findByObservationIdAndDeleted(o.getId(), false);
                    observationList.add(ObservationNewVo.of(o, optionList));
                });
                return observationList;
            }
        }
    }

    @Transactional
    @Override
    public Boolean addObservationRecord(String childrenId, Integer category, String coursePlanId, List<Map> observationList, String staffId,String staffName, String areaId) {
        CoursePlanClasses coursePlan = coursePlanClassesRepository.getOne(coursePlanId);
        if (Objects.isNull(coursePlan))
            throw new BusinessException(CATEGORY_ERROR, "没有找到该课程");

        List<ChildListDO> observationChildren = childrenObservationRecordRepository.findChildrenByPlan(coursePlanId, category, childrenId);
        if (Objects.nonNull(observationChildren) && observationChildren.size() != 0)
            throw new BusinessException(OBSERVATION_TESTED, "该宝宝这节课已经做过观测了");

        if (CourseConstant.Category.EARLY.codeOf() == coursePlan.getCategory()){
            //修改宝宝状态
            ChildrenCourseItem item = childrenCourseItemRepository.findByCoursePlanIdAndChildrenId(coursePlanId, childrenId);
            item.setStatus(ChildrenCourseConstant.ItemStatus.EVALUATED.codeOf());
            childrenCourseItemRepository.save(item);
        }
        ObservationNewRecord record = ObservationNewRecord.of(category, coursePlanId, staffId,staffName, childrenId, coursePlan.getCourseType());

        observationNewRecordRepository.save(record);


        Integer totalScore=0;
        String images = "";
        for (Map observation : observationList){
            String options=observation.get("optionId").toString();
            if(options!=""){
                String imageUrl = observation.get("imgUrl").toString();

                String[] optionIds=options.split(",");
                for(int i=0;i<optionIds.length;i++){
                    ObservationNewOption observationOption = observationNewOptionRepository.getOne(optionIds[i].toString());
                    ObservationNew observationNew = observationNewRepository.getOne(observation.get("id").toString());
                    ObservationNewQuestionRecord questionRecord = new ObservationNewQuestionRecord();

                    questionRecord.setScore(observationOption.getScore());
                    questionRecord.setOptionId(observationOption.getId());
                    questionRecord.setOptionTitle(observationOption.getTitle());
                    questionRecord.setObservationId(observationNew.getId());
                    questionRecord.setObservationQuestion(observationNew.getQuestion());
                    questionRecord.setObservationRecordId(record.getId());
                    questionRecord.setResourceUrl(imageUrl);
                    observationNewQuestionRecordRepository.save(questionRecord);
                    totalScore = totalScore + questionRecord.getScore();
                }

                if(!StringUtils.isEmpty(imageUrl)){
                    if(images.length() > 0){
                        images += "|";
                    }
                    images += imageUrl;
                }
            }
            
        	//ObservationNewOption observationOption = observationNewOptionRepository.getOne(observation.get("optionId").toString());
        //    ObservationNew observationNew = observationNewRepository.getOne(observation.get("id").toString());
     //       ObservationNewQuestionRecord questionRecord = new ObservationNewQuestionRecord();
      //      questionRecord.setObservationId(observationNew.getId());
       //     questionRecord.setObservationQuestion(observationNew.getQuestion());
      //      questionRecord.setObservationRecordId(record.getId());
            
          //  questionRecord.setScore(observationOption.getScore());
          //  questionRecord.setOptionId(observationOption.getId());
          //  questionRecord.setOptionTitle(observationOption.getTitle());
 //           questionRecord.setResourceUrl(observation.get("imgUrl").toString());
 //           if(!StringUtils.isEmpty(questionRecord.getResourceUrl())){
//                if(images.length() > 0){
 //                   images += "|";
 //               }
 //               images += questionRecord.getResourceUrl();
//            }
//            observationNewQuestionRecordRepository.save(questionRecord);
//            totalScore = totalScore + questionRecord.getScore();
        }
        record.setScore(totalScore);
        observationNewRecordRepository.save(record);

        //feed 增加
        String childrenName = "";
        String courseName = coursePlan.getCourseName();
        String title = String.format("%s %s的评测报告", childrenName, courseName);
        String content = "宝贝最新观测点报告新鲜出炉啦，老师都竖起了大拇指，继续加油！";
        Feeds feed = feedsService.save(staffId, childrenId, areaId, "", FeedsConstant.OBSERVATION_NEW, title, content, images, "", record.getId());

        //Patch for a little coding mistake
        //Patch finished

        //微信推送
        wxPushService.pushObservationNewRecord(staffName, record,null, feed.getId());
        return true;
    }

    @Transactional
    @Override
    public Boolean createObservation(String observationJson, Integer category, String coursePlanId, Integer courseType) {
       	List<Map> observationMap = JsonValidateUtil.readToList(observationJson, "观测点Json解析错误");
        Integer observationIdx = 1;
        for (Map m :observationMap){
            ObservationNew observationNew = ObservationNew.of(m, coursePlanId, category, courseType, observationIdx++);
            observationNewRepository.save(observationNew);
            List<Map> optionMapList = (List<Map>) m.get("options");
            List<ObservationNewOption> options = Lists.newArrayList();
            Integer optionIdx = 1;
            for (Map option :optionMapList)
                options.add(ObservationNewOption.of(option, observationNew.getId(), optionIdx++));
            observationNewOptionRepository.saveAll(options);
        }
        return true;
    }


    @Override
    public List<ObservationNewType> findAllType() {
        return observationNewTypeRepository.findByDeletedOrderByCodeAsc(false);
    }

    @Override
    public List<ObservationChildrenListVo> getChildrenByPlan(String coursePlanId, Integer category) {
//        String today = DateUtil.millisToDateTime(System.currentTimeMillis(), "yyyy-MM-dd");
        if (CourseConstant.Category.EARLY.codeOf() == category){
            List<ChildrenCourseItemDO> itemList = childChildrenCourseItemRepository.findByChildrenByCoursePlanId(coursePlanId);
            List<ChildListDO> observationChildren = childrenObservationRecordRepository.findChildrenByPlan(coursePlanId, CourseConstant.Category.EARLY.codeOf(), null);
            List<ObservationChildrenListVo> orChildrenListVos = itemList.stream().map(o -> ObservationChildrenListVo.ofEarlyCourse(o, observationChildren)).collect(Collectors.toList());
            return orChildrenListVos;
        }else {
            CoursePlanClasses nurseryClasses = coursePlanClassesRepository.getOne(coursePlanId);
            List<ChildrenCheckRecordDO> checkRecordDOList = childrenService.findChildCheckRecordByClasses(nurseryClasses.getClassesId());
            List<ChildListDO> observationChildren = childrenObservationRecordRepository.findChildrenByPlan(coursePlanId, CourseConstant.Category.NURSERY.codeOf(), null);
            List<ObservationChildrenListVo> orChildrenListVos = checkRecordDOList.stream().map(o -> ObservationChildrenListVo.ofNurseryCourse(o, observationChildren)).collect(Collectors.toList());
            return orChildrenListVos;
        }
    }

    @Override
    public String observationUpload(Integer mediaType, MultipartFile[] files) {
        String resourceUrl = "";
        if (Objects.nonNull(files) && files.length != 0)
            resourceUrl += uploadService.uploadObservationRecordImg(mediaType, files);

        return resourceUrl;
    }

    @Transactional
    @Override
    public Boolean refreshObservation(String coursePlanId, String observationJson, Integer category, Integer courseType) {
        List<ObservationNew> observationList = observationNewRepository.findByCoursePlanId(coursePlanId);
        for (ObservationNew observation: observationList){
            observationNewOptionRepository.deleteByObservationId(observation.getId());
            observationNewRepository.deleteById(observation.getId());
        }

        createObservation(observationJson, category, coursePlanId, courseType);
        return true;
    }
}
